package com.repeat.gateway.handler;
import com.alibaba.csp.sentinel.adapter.spring.webflux.callback.BlockRequestHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.repeat.gateway.enums.GatewayEnum;
import com.repeat.gateway.response.GatewayResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Slf4j
@Component
public class CustomGatewayBlockHandler implements BlockRequestHandler  {
    @Override
    public Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable throwable) {
        int code = GatewayEnum.BAD_GATEWAY.getCode();
        String message = GatewayEnum.BAD_GATEWAY.getMsg();
        HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
        log.info("throwable ", throwable);
        // 如果需要，可以根据异常类型提供更具体的信息
        if (throwable instanceof BlockException) {
            // 通用信息
            log.info("block getRequest {}", exchange.getRequest().getPath().value());
            // 判断具体的异常类型
            if (throwable instanceof FlowException) {
                status = HttpStatus.TOO_MANY_REQUESTS;
                code = GatewayEnum.TOO_MANY_REQUESTS.getCode();
                message = GatewayEnum.TOO_MANY_REQUESTS.getMsg();
            } else if (throwable instanceof DegradeException) {
                status = HttpStatus.SERVICE_UNAVAILABLE; // 503
                code = GatewayEnum.SERVICE_UNAVAILABLE.getCode();
                message = GatewayEnum.SERVICE_UNAVAILABLE.getMsg();
            } else if (throwable instanceof AuthorityException) {
                status = HttpStatus.FORBIDDEN; // 403
                code = GatewayEnum.FORBIDDEN.getCode();
                message = GatewayEnum.FORBIDDEN.getMsg();

            }
            // ... 可以继续处理其他类型的 BlockException
        }
        GatewayResponse response = new GatewayResponse(
                code,
                message,
                null
        );
        // 使用 ServerResponse 构建响应
        return ServerResponse.status(status)
                .contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromValue(response));
    }
}
